package com.bee.study.web;

import com.bee.study.entity.Article;
import com.bee.study.repository.ArticleRepository;
import com.bee.study.repository.CarsRepository;
import com.bee.study.util.JsonUtils;
import com.google.common.collect.Lists;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @version 1.0.0
 * @Author yong.Mr
 * @data 2019-8-9
 */
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * CURD操作ES的数据库
     */
    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private CarsRepository carsRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @RequestMapping("/es")
    public String test2(){
        // 即创建索引，并且配置了映射关系
        elasticsearchTemplate.createIndex(Article.class);
//        elasticsearchTemplate.createIndex("artcle_blog","{'settings':'sad'}");
        // 创建映射关系
//        elasticsearchTemplate.putMapping(Article.class);
//        elasticsearchTemplate.createIndex("artcle_blog");
//        elasticsearchTemplate.putMapping("artcle_blog","article",
//                "{'settings':{}}");
//        elasticsearchTemplate.putMapping(Article.class,"{'settings':{}}");
        Article article = new Article();
        /**
         * 如果不指定id，_id,es的唯一键会为null
         * {"_index":"article_blog","_type":"article","_id":"null","_score":1.0,"_source":{"id":null,}}
         */
        article.setId(null);  // ES的更新数据，其实是insert数据，只是插入_id一样的数据，ES会自动将库中存在同样的_id删除，之后再将新的数据添加到ES库中
        article.setTitle("21");
        article.setContent("321");
        article.setCreateTime(new Date());
        article.setUpdateTime(new Date());
        // 返回的是新插入ES库中的数据
        Article save = articleRepository.save(article);
        // 批量添加
        ArrayList<Article> articles = Lists.newArrayList(new Article(), new Article());
        // 返回都是添加进ES库中的数据
        Iterable<Article> articles1 = articleRepository.saveAll(articles);


        return JsonUtils.objectToJson(article);
    }

    @RequestMapping("/deleteArticle")
    public String deleteByArticle(){
        Article article = new Article();
        article.setId(3291529336880973483L);  // ES的更新数据，其实是insert数据，只是插入_id一样的数据，ES会自动将库中存在同样的_id删除，之后再将新的数据添加到ES库中
        article.setTitle("21");
        article.setContent("321");
        article.setCreateTime(new Date());
        article.setUpdateTime(new Date());
        // 根据_id删除一条记录
//        articleRepository.deleteById(123L);
        // 清除所有记录
        carsRepository.deleteAll();
        // 相当于articleRepository.deleteById(123L); 是根据_id删除的
        // @Id
        // @Field(type = FieldType.Long, store = true)
        // private Long id;  // ES的唯一键
//        articleRepository.delete(article);
        // 批量删除(根据List<Article> articles中的id批量删除)
        List<Article> articles = Lists.newArrayList(new Article(), new Article());
//        articleRepository.deleteAll(articles);
        return JsonUtils.objectToJson(article);
    }

    @RequestMapping("/data")
    public String queryData(){
        // 查询ES的所有数据
        Iterable<Article> all = articleRepository.findAll();
        all.forEach(x -> System.out.println(x.toString()));
        // 设置排序字段，进行排序
        Iterable<Article> createTime = articleRepository.findAll(new Sort("createTime"));
        // 设置分页, 加排序
        Pageable pageable = PageRequest.of(0, 20, Sort.by("createTime"));
        Page<Article> all1 = articleRepository.findAll(pageable);
        // 批量查询
        Iterable<Article> allById = articleRepository.findAllById(Lists.newArrayList(123L, 234L));
        // 根据_id进行查询
        Optional<Article> byId = articleRepository.findById(123L);
        Article article1 = byId.get();
        // 根据条件查询数据，并且设置分页
        Page<Article> search = articleRepository.search(QueryBuilders.termsQuery("title", "ca"), pageable);
        Article article = articleRepository.findArticleByContentAndTitle("content", "title");
        System.out.println(article.toString());
        // 复杂查询
//        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery();
//        articleRepository.search(nativeSearchQuery);
//        Iterable<Article> all = articleRepository.findAll(Sort.by(Sort.Direction.ASC, "price", "grade"));
        return JsonUtils.objectToJson(search);
    }

    @RequestMapping("/title")
    public String queryDataByTitle(){
        List<Article> articleByTitle = articleRepository.findArticleByTitle("21");
        articleByTitle.forEach(x -> System.out.println(x.toString()));
        return JsonUtils.objectToJson(articleByTitle);
    }

    @RequestMapping("/native")
    public String queryNativeData(){
        // 设置查询条件
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("21").defaultField("title").analyzer("ik_smart");
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withIndices("article_blog")
                .withTypes("article")
                .withQuery(queryBuilder)
                .withHighlightFields(new HighlightBuilder.Field("title"))
                .withPageable(PageRequest.of(0,20, Sort.by(Sort.Order.desc("createTime"))))
                .withSort(SortBuilders.fieldSort("createTime").order(SortOrder.ASC))  // 排序
                .withSort(SortBuilders.fieldSort("updateTime").order(SortOrder.DESC))
                .build();
        // 使用ElasticsearchTemplate查询数据
        List<Article> articles = elasticsearchTemplate.queryForList(query, Article.class);
        articles.stream().forEach(x -> {
            System.out.println(x.toString());
        });
        return articles.toString();
    }

}
